package com.paw.ruoyi.admin.biz.service;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.util.StrUtil;
import com.paw.ruoyi.admin.common.constant.CommonConstant;
import com.paw.ruoyi.admin.common.constant.Constants;
import com.paw.ruoyi.admin.common.context.UserContext;
import com.paw.ruoyi.admin.common.context.UserContextHolder;
import com.paw.ruoyi.admin.common.enums.UserTypeEnum;
import com.paw.ruoyi.admin.core.util.RedisUtilService;
import com.paw.ruoyi.admin.async.AsyncFactory;
import com.paw.ruoyi.admin.async.AsyncManager;
import com.paw.ruoyi.admin.common.AjaxResult;
import com.paw.ruoyi.admin.domain.SysUser;
import com.paw.ruoyi.admin.service.ISysConfigService;
import com.paw.ruoyi.admin.service.ISysUserService;
import com.paw.ruoyi.admin.utils.DateUtils;
import com.paw.ruoyi.admin.core.util.ServletUtils;
import com.paw.ruoyi.admin.utils.ip.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * 登录校验方法
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class SysLoginService {

  @Autowired
  private TokenService tokenService;

//    @Resource
//    private AuthenticationManager authenticationManager;

  @Autowired
  private RedisUtilService redisUtilService;

  @Autowired
  private ISysUserService userService;

  @Autowired
  private ISysConfigService configService;

  @Autowired
  private PasswordEncoder passwordEncoder;


  @Autowired
  private SysPermissionService sysPermissionService;

  /**
   * 登录验证
   *
   * @param username 用户名
   * @param password 密码
   * @param code     验证码
   * @param uuid     唯一标识
   * @return 结果
   */
  public AjaxResult login (String username, String password, String code, String uuid) {
    boolean captchaOnOff = configService.selectCaptchaOnOff();
    // 验证码开关
    if (captchaOnOff) {
      String validMsg =  validateCaptcha(username, code, uuid);
      if(StrUtil.isNotEmpty(validMsg)){
        return AjaxResult.error(validMsg);
      }
    }

    SysUser sysUser = userService.selectUserByUserName(username);
    String encodePassword = passwordEncoder.encode(password);
    log.info("login encodePassword: {}", encodePassword);

    boolean matched = passwordEncoder.matches(password, sysUser.getPassword());
    if (!matched) {
      AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "用户不存在/密码错误"));
      return AjaxResult.error("用户名密码错误");
    }

    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"));

    recordLoginInfo(sysUser.getUserId());

    // 获取权限
    Set<String> permissions = sysPermissionService.getMenuPermission(sysUser);
//
//    // 角色
//    Set<String> roles = sysPermissionService.getRolePermission(sysUser);


    UserContext userContext = new UserContext();
    userContext.setUserId(sysUser.getUserId());
    userContext.setUserName(sysUser.getUserName());
    userContext.setNickName(sysUser.getNickName());
    userContext.setUserPhone(sysUser.getPhonenumber());
    userContext.setPermissions(permissions);
    userContext.setUserType(UserTypeEnum.ADMIN.getCode());

    // 生成token
    String token = tokenService.createToken(userContext);

    AjaxResult ajaxResult = AjaxResult.success();
    ajaxResult.put(Constants.TOKEN, token);

    return ajaxResult;
  }

  /**
   * 校验验证码
   *
   * @param username 用户名
   * @param code     验证码
   * @param uuid     唯一标识
   * @return 结果
   */
  public String validateCaptcha (String username, String code, String uuid) {
    String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
    String captcha = redisUtilService.getCacheObject(verifyKey);
    redisUtilService.del(verifyKey);
    if (captcha == null) {
      AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码已失效"));
      return "验证码过期";
    }
    if (!code.equalsIgnoreCase(captcha)) {
      AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误"));
      return "验证码错误";
    }
    return null;
  }

  /**
   * 记录登录信息
   *
   * @param userId 用户ID
   */
  public void recordLoginInfo (Long userId) {
    SysUser sysUser = new SysUser();
    sysUser.setUserId(userId);
    sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
    sysUser.setLoginDate(DateUtils.getNowDate());
    userService.updateUserProfile(sysUser);
  }

  public void logout (HttpServletRequest request) {
    if (UserContextHolder.getUserId()!=null) {
      String userName = UserContextHolder.getUser().getUserName();
      // 删除用户缓存记录
      tokenService.delLoginUser(request.getHeader(CommonConstant.TOKEN));
      // 记录用户退出日志
      AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
    }
  }
}
